//
// Created on 2025/11/4.
//
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
// please include "napi/native_api.h".

#ifndef PRE_EXPORT_BACKGROUND_CACHE_H
#define PRE_EXPORT_BACKGROUND_CACHE_H
#include <map>
#include <memory>

#include "codec_common.h"

#undef LOG_TAG
#define LOG_TAG "BackgroundCache"

class BackgroundCacheManager;

class BackgroundCache: public std::enable_shared_from_this<BackgroundCache> {
public:
    // 外部接口
    // 单hash缓存实例
    BackgroundCache(uint64_t frameCacheSize, uint32_t codecWidth, uint32_t codecHeight, 
                    uint32_t codecFrameRate, OH_AVPixelFormat codecPixelFormat);
    
    ~BackgroundCache();
    
    ResultCode SetHash(const std::string &hash);
    
    ResultCode SetCachePath(const std::string &cachePath);
    
    bool TestFrameValid(uint64_t frameIndex, ExportType exportType);
    
    bool CheckFrameRange(uint64_t frameIndex, uint64_t *beginIndex, 
                         uint64_t *endIndex, ExportType exportType);
    
    ResultCode PutFrame(uint64_t frameIndex, void *inFrameData, uint32_t frameWidth,
                        uint32_t frameHeight, uint32_t widthPitch, ExportType exportType);

    ResultCode GetFrame(uint64_t frameIndex, void **outFrameData, uint32_t *outFrameSize, ExportType exportType);
    
    ResultCode NotifyInterrupt();
    
    ResultCode RunUntilEncodeFinished(uint64_t timeoutInSecond);
    
    ResultCode ExportFinished();

    // 内部接口
    bool IsInterrupt();
    std::string GetHashString() { return hashString_; }
    std::string GetCachePath(ExportType exportType);
    uint64_t GetSize();
    ResultCode Resize(uint64_t resize);
    uint32_t GetFrameRate() { return codecFrameRate_; }
    uint32_t GetWidth() { return codecWidth_; }
    uint32_t GetHeight() { return codecHeight_; }
    OH_AVPixelFormat GetPixelFormat() { return codecPixelFormat_; }
    CacheInfo* GetCacheInfoByIndex(uint64_t frameIndex, ExportType exportType);
    ResultCode SetCacheInfoByIndex(uint64_t frameIndex, CacheInfo* cacheInfo, ExportType exportType);
    bool CheckEnCodeRange(uint64_t *frameStart, uint64_t *frameEnd, ExportType exportType);
    bool CheckPreExportEnCodeRange(uint64_t *frameStart, uint64_t *frameEnd);
    bool CheckExportEnCodeRange(uint64_t *frameStart, uint64_t *frameEnd);
    
    ResultCode CodecResultHandle(uint64_t start, uint64_t end, 
        std::unordered_map<uint64_t, std::string>& result, ExportType exportType);
    
    bool CheckExportFrameRange(uint64_t frameIndex, uint64_t *beginIndex,
                               uint64_t *endIndex, ExportType exportType);
    ResultCode UpdateExportInvalidRange(uint64_t beginIndex, uint64_t endIndex, ExportType exportType);
    
    bool CheckCachedFrameRange(uint64_t frameIndex, uint64_t *beginIndex, 
                                     uint64_t *endIndex, ExportType exportType);
    
private:
    ResultCode UpdateIFrameRange(uint64_t start, uint64_t end);
    bool TestFrameNeedInputFrame(uint64_t frameIndex, ExportType exportType);
    
    uint32_t codecWidth_ = 0;
    uint32_t codecHeight_ = 0;
    uint32_t codecFrameRate_ = 60;
    OH_AVPixelFormat codecPixelFormat_ = AV_PIXEL_FORMAT_NV12;
    
    BackgroundCacheManager *manager_ = nullptr;
    std::atomic<uint64_t> cacheSize_ = 0;
    std::string cachePath_ = "";
    std::string hashString_ = "";
    std::string sPSCachePath_ = "";
    
    std::atomic<bool> interrupted_;
    
    std::mutex mutex_;
    CacheInfo* cacheInfoList_;
    
    std::mutex exportMutex_;
    std::map<uint64_t, CacheInfo> exportCacheInfoMap_;
};


#endif //PRE_EXPORT_BACKGROUND_CACHE_H
